package org.jpropelleralt.jview.factory.impl;

import java.awt.Color;

import org.jpropelleralt.jview.JView;
import org.jpropelleralt.jview.factory.JViewFactory;
import org.jpropelleralt.jview.general.impl.GeneralRendererDefault;
import org.jpropelleralt.jview.general.impl.GeneralRendererDefault.RenderFormat;
import org.jpropelleralt.jview.ref.impl.BooleanView;
import org.jpropelleralt.jview.ref.impl.ColorView;
import org.jpropelleralt.jview.ref.impl.GeneralView;
import org.jpropelleralt.jview.ref.impl.NumberView;
import org.jpropelleralt.jview.ref.impl.StringView;
import org.jpropelleralt.jview.ref.impl.BooleanView.ControlType;
import org.jpropelleralt.ref.Ref;
import org.jpropelleralt.view.Views;
import org.jpropelleralt.view.update.UpdateManager;

/**
 * Default implementation of {@link JViewFactory}
 */
public class JViewFactoryDefault implements JViewFactory {

	private final UpdateManager updateManager;
	

	/**
	 * Create a new {@link JViewFactoryDefault} using the
	 * default {@link UpdateManager} from {@link Views}
	 */
	public JViewFactoryDefault() {
		this(Views.updateManager());
	}
	
	/**
	 * Create a new {@link JViewFactoryDefault}
	 * @param updateManager		The {@link UpdateManager} to use
	 */
	public JViewFactoryDefault(UpdateManager updateManager) {
		this.updateManager = updateManager;
	}
	
	//We accept a valueClass that must match T, and so we can
	//cast Ref to Ref<T> safely as long as we check valueClass first.
	@SuppressWarnings("unchecked")
	@Override
	public <T> JView viewFor(Class<T> valueClass, Ref<T> ref,
			Ref<Boolean> locked, Ref<String> name) {
		
		//Number types
		if (valueClass == Integer.class) {
			return NumberView.createInteger((Ref<Integer>)ref, locked, new Integer(1), updateManager);
		} else if (valueClass == Long.class) {
				return NumberView.createLong((Ref<Long>)ref, locked, new Long(1), updateManager);
		} else if (valueClass == Float.class) {
			return NumberView.createFloat((Ref<Float>)ref, locked, new Float(0.1f), updateManager);
		} else if (valueClass == Double.class) {
			return NumberView.createDouble((Ref<Double>)ref, locked, new Double(0.1), updateManager);
			
		//String as single line editor
		} else if (valueClass == String.class) {
			return StringView.create((Ref<String>)ref, false, locked, updateManager);
			
		//Boolean as checkbox
		} else if (valueClass == Boolean.class) {
			return BooleanView.create((Ref<Boolean>)ref, name, locked, updateManager, ControlType.CHECK_BOX);

		//Color
		} else if (valueClass == Color.class) {
			return ColorView.create((Ref<Color>)ref, locked, updateManager);

		//Fall back to a general view with single line renderer
		} else {
			return GeneralView.create(ref, new GeneralRendererDefault(RenderFormat.SINGLE_LINE), updateManager);
		}
		
	}

}
